﻿#include <cstdlib> // For std::putenv
#include <cstring> // For std::strdup
#include <time.h>
#include <QFileDialog>
#include <QFile>
#include <fstream>
#include <iostream>
#include <QString>

#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/document/IndexedPropertyValues.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <cppuhelper/bootstrap.hxx>
#include <osl/mutex.hxx>
#include <rtl/ustring.hxx>
#include <iostream>
#include <sal/main.h>
#include <osl/file.hxx>
#include <osl/process.h>
#include <rtl/process.h>
#include <rtl/ustrbuf.hxx>

#include "GemerateFinalReport.h"
#include "FinalReportData.h"
#include "ElaMessageBar.h"
#include "MainWindow.h"
#include "CloseCurrentReport.h"

using namespace std;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::bridge;
using namespace com::sun::star::frame;
using namespace com::sun::star::sheet;
using namespace com::sun::star::registry;
using namespace com::sun::star::text;
using namespace rtl;

using com::sun::star::beans::PropertyValue;

using com::sun::star::text::XTextDocument;
using com::sun::star::text::XText;
using com::sun::star::text::XTextCursor;

namespace GenerateReport
{
	GemerateFinalReport::GemerateFinalReport()
	{
	}
	//test1::~Test1()
	//{
	//}

	void GemerateFinalReport::actionSlot_GemerateFinalReport()
	{

		QString _dir = QString("C:/");
		QString _conSuffix = QString("*.docx");
		
		QString _title = QString("Gemerate Final Report");
		QString _defaultName = GenerateReportBaseInstance->getCurrentReportName();
		QString _selectNameFilter = "*.docx";
		QString _filenamePath = QFileDialog::getSaveFileName(nullptr, _title, _dir + _defaultName, _conSuffix, &_selectNameFilter);
		if (_filenamePath.isEmpty())
        {
            return;
        }
		else
        {
            //获取不带路径的文件名
            string::size_type iPos = _filenamePath.toStdString().find_last_of('/') + 1;
            string filenametemp = _filenamePath.toStdString().substr(iPos, _filenamePath.toStdString().length() - iPos);
            string filename = filenametemp.substr(0, filenametemp.rfind("."));
            //检测是否有同名文档在打开状态，如果有则提示关闭
            if(QFile::exists(_filenamePath))
            {
                std::ifstream file(_filenamePath.toStdString(), std::ios::in);
                if (file.is_open())//检测有没有被其他软件打开
                {
                    file.close();
                    auto _isopen = GenerateReportBaseInstance->checkReportWidgetIsOpen(QString::fromStdString(filename));
                    if (_isopen)//检测在本软件内是否打开
                    {
                        ElaMessageBar::error(ElaMessageBarType::PositionPolicy::Top, "生成失败", QStringLiteral("同名文档处于打开状态，请先关闭同名文档，或修改本文档名称"), 3000, GenerateReport::GenerateReportBase::getinstance()->getMainWindow());
                    }
                    else
                    {
                        saveLibreOfficeDocumentAsDocx(filename, _filenamePath.toStdString());
                    }
                }
                else
                {
                    ElaMessageBar::error(ElaMessageBarType::PositionPolicy::Top, "生成失败", QStringLiteral("同名文档已在其他软件中打开，请先关闭同名文档，或修改本文档名称"), 3000, GenerateReport::GenerateReportBase::getinstance()->getMainWindow());
                    return;
                }
            }
            else
                saveLibreOfficeDocumentAsDocx(filename, _filenamePath.toStdString());
        }
	}

	void GemerateFinalReport::saveLibreOfficeDocumentAsDocx(const std::string& reportName, const std::string& outputDocxPath)
	{
		auto _xComponent = GenerateReportBaseInstance->getTextDocument();
		// 保存文档为docx格式
		Reference<XStorable> xStorable(_xComponent, UNO_QUERY);
		if (!xStorable.is()) {
			std::cerr << "Failed to get XStorable interface." << std::endl;
			return;
		}

		Sequence<PropertyValue> storeArgs(1);
		storeArgs[0].Name = OUString("FilterName");
		storeArgs[0].Value <<= OUString("MS Word 2007 XML");

		//OUString _outputPath = OUString("file:///") +  OUString::createFromAscii(outputDocxPath.c_str());
		OUString _outputPath = OUString("file:///") + OUString::fromUtf8(outputDocxPath.c_str());
		try {
			xStorable->storeToURL(
				_outputPath,
				// OUString("file:///F:/LibreofficeTest/export1.docx"),
				storeArgs
			);
			std::cout << "Document successfully saved as docx format." << std::endl;

			time_t now = time(nullptr); // 获取当前时间的秒数
			tm* ltm = localtime(&now); // 转换为本地时间

			QString _currentTime = QString("%1-%2-%3  %4:%5:%6").arg(1900 + ltm->tm_year).arg(1 + ltm->tm_mon).arg(ltm->tm_mday).arg(ltm->tm_hour).arg(ltm->tm_min).arg(ltm->tm_sec);
			QStringList _finalReportInfo{  };
			_finalReportInfo .append( QString::fromStdString(reportName));
			_finalReportInfo.append( QString::fromStdString(outputDocxPath));
			_finalReportInfo.append(_currentTime);
			_finalReportInfo.append(QString("true"));
			FinalReportDataInstance->appendFinalReport(_finalReportInfo);


			GenerateReport::CloseCurrentReport _crr;
			_crr.closeReportExcute();
            ElaMessageBar::success(ElaMessageBarType::PositionPolicy::Top, QStringLiteral("保存成功"), QStringLiteral("报告生成成功，点击报告记录查看！"), 3000, GenerateReport::GenerateReportBase::getinstance()->getMainWindow());
		}
		catch (const Exception& e) {
			std::cerr << "Error saving document as docx format: " << e.Message << std::endl;
		}
	}
}
